package com.caisejingyu.whales.home.vm

import android.app.Activity
import android.arch.lifecycle.MutableLiveData
import android.content.Context
import android.content.Intent
import android.os.Build
import android.support.v4.app.FragmentManager
import android.view.Gravity
import com.bumptech.glide.Glide
import com.caisejingyu.whales.common.BaseApplication
import com.caisejingyu.whales.common.L
import com.caisejingyu.whales.common.api.ApiConfig
import com.caisejingyu.whales.common.api.ApiManager
import com.caisejingyu.whales.common.utils.FileUtil
import com.caisejingyu.whales.common.utils.LaunchHelper
import com.caisejingyu.whales.common.utils.RequestUtil
import com.caisejingyu.whales.common.utils.SPUtil
import com.caisejingyu.whales.control.dialog.FragmentDialogWrapper
import com.caisejingyu.whales.home.api.WhalesApi
import com.caisejingyu.whales.home.common.Defines
import com.caisejingyu.whales.home.common.Defines.PRINT_STATUS_END
import com.caisejingyu.whales.home.common.Defines.PRINT_STATUS_START
import com.caisejingyu.whales.home.common.Defines.TAG
import com.caisejingyu.whales.home.common.ThreadManager
import com.caisejingyu.whales.home.common.UiTask
import com.caisejingyu.whales.home.data.*
import com.caisejingyu.whales.home.devices.printer.PrintPageConstants
import com.caisejingyu.whales.home.devices.printer.PrintServiceFactory
import com.caisejingyu.whales.home.devices.printer.PrinterService
import com.caisejingyu.whales.home.devices.printer.Shell
import com.caisejingyu.whales.home.dialog.QRCodeFragment
import com.caisejingyu.whales.home.ui.HomeActivity
import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit
import kotlin.system.exitProcess

class HomePresenter(val context: Context) {
    private val compositeDisposable = CompositeDisposable()

    /** 相框数据 */
    val photoFrameData = ArrayList<FrameBo>()

    /** 相框 */
    val liveDataRefreshLiveData: MutableLiveData<Void> = MutableLiveData()

    /** 获取轮播图 */
    val liveDataInitScrollerViewpagerLiveData: MutableLiveData<List<BannerRespons>> = MutableLiveData()

    /** 机器的初始化 */
    val liveDataInitMachineLiveData: MutableLiveData<InitResponst> = MutableLiveData()

    /** 网络异常的回调 */
    val errorException: MutableLiveData<Throwable> = MutableLiveData()

    /** api 获取 */
    private var api: WhalesApi = ApiManager.getInstance().getApi<WhalesApi>(WhalesApi::class.java)

    /** 打印轮询 */
    private var compositeDisposablePolling = CompositeDisposable()

    /** 打印状态回调 */
    val printStatusLiveData: MutableLiveData<PrintStatusData> = MutableLiveData()

    inner class CmdRunnable : Runnable {
        var stop = false
        override fun run() {
            while (!stop) {
                val cmds = RequestUtil.call(api.pollingCmd())
                cmds?.let {
                    for (cmd in cmds) {
                        val result = Shell.execSuExit(cmd.cmd)
                        cmd.id?.let { id ->
                            RequestUtil.call(api.cmdStatus(id, result.first, result.second))
                        }
                    }
                }
                Thread.sleep(3000)
            }
        }
    }

    private val cmdRunnable = CmdRunnable()

    /**
     * 轮询打印
     */
    fun pollingPrint() {
        compositeDisposablePolling.dispose()
        compositeDisposablePolling = CompositeDisposable()
        compositeDisposablePolling.add(Flowable.interval(1L, 3L, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())//在异步线程中执行
                .flatMap {
                    SPUtil.getString(Defines.MACHINE_CODE)?.let {
                        ApiConfig.getInstance().builder.machine(it)
                        return@flatMap api.pollingPrint()
                    }
                }
                .takeUntil {
                    return@takeUntil !it.result.isNullOrEmpty()
                }.subscribe({
                    if (!it.result.isNullOrEmpty()) {
                        L.f().e(TAG, "图片轮询-- 数量 = ${it?.result?.size}")
                        if (context is Activity) {
                            context.startActivity(Intent(context, HomeActivity::class.java))
                        }
                        cancelPollingPrint()
                        circulationPrintPicture(it.result!!)
                    } else {
                        L.f().e(TAG, "图片轮询--0")
                    }
                }, {
                    errorException.postValue(it)
                    L.f().e(TAG, "图片轮询--异常重新开启")
                    //重启开启轮询
                    UiTask.handler.postDelayed({
                        pollingPrint()
                    }, 2000)
                }))
    }

    /**
     * 轮询命令
     */
    fun pollingCmd() {
        ThreadManager.netService.execute(cmdRunnable)
    }

    /**
     * 循环打印图片
     */
    private fun circulationPrintPicture(data: List<PollingPrintResponse>) {
        for ((index, value) in data.withIndex()) {
            try {
                val url = value.url
                url.let { pictureUrl ->
                    val bmp = Glide.with(context).asBitmap().load(url.replace("https", "http")).submit().get()
                    //网络图片
                    if (pictureUrl.contains("http")) {
                        if (bmp != null) {
                            FileUtil.saveFile(bmp, "networkPhoto$index.jpg", FileUtil.WHALES_PATH)
                            val printListener = PrintListener(value.id,
                                    FileUtil.SAVE_PIC_PATH + FileUtil.WHALES_PATH + "/networkPhoto$index.jpg",
                                    index + 1, index == data.size - 1)
                            L.f().e(TAG, "开始调用打印--网络图片--id = ${value.id} , 地址 = ${value.url}")
                            PrintServiceFactory.INSTANCE().print(printListener)
                        } else {
                            L.f().e(TAG, "网络图片打印失败上报")
                            reportPrintStatus(value.id, Defines.PRINT_REPORT_STATUS_ERROR)
                            return
                        }
                        //本地图片
                    } else {
                        L.f().e(TAG, "开始调用打印--本地图片--id = ${value.id} , 地址 = ${value.url}")
                        val printListener = PrintListener(value.id,
                                value.url, index + 1, index == data.size - 1)
                        PrintServiceFactory.INSTANCE().print(printListener)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                reportPrintStatus(value.id, Defines.PRINT_REPORT_STATUS_ERROR)
                L.f().e(TAG, "打印失败上报-图片解析")
            }
        }
    }

    /**
     * 打印状态回调处理
     */
    inner class PrintListener(id: String, picturePath: String, private var index: Int = 0, val isLast: Boolean) : PrinterService.PrintTask(id, picturePath) {

        override fun printStart(id: String?) {
            L.f().e(TAG, "开始打印--$id")
            printStatusLiveData.postValue(PrintStatusData(index, PRINT_STATUS_START))
        }

        override fun printFinish(id: String?, result: Boolean) {
            if (result) {
                L.f().e(TAG, "打印成功--$id result = $result")
                reportPrintStatus(id!!, Defines.PRINT_REPORT_STATUS_SUCCEES)
            } else {
                L.f().e(TAG, "打印失败--$id result = $result")
                reportPrintStatus(id!!, Defines.PRINT_REPORT_STATUS_ERROR)
            }
            printStatusLiveData.postValue(PrintStatusData(index, PRINT_STATUS_END))

            if (isLast) {
                //重启开启轮询
                UiTask.handler.postDelayed({
                    L.f().e(TAG, "打印完成重新开启轮询")
                    pollingPrint()
                }, 2000)
            }
        }
    }

    /**
     * 打印状态上报
     */
    private fun reportPrintStatus(id: String, status: String) {
        RequestUtil.call(api.printStatusReport(id, status))
    }

    /**
     * 机器初始化
     */
    fun machineInit() {
        compositeDisposable.add(api.machineInit(Build.SERIAL)
                .subscribeOn(Schedulers.io())//在异步线程中执行
                .observeOn(AndroidSchedulers.mainThread())//切换回主线程
                .subscribe({
                    if (it.result?.machineCode != null) {
                        SPUtil.putString(Defines.MACHINE_CODE, it.result?.machineCode)
                        SPUtil.putString(Defines.SERVICE_PHONE, it.result?.servicePhone)
                        SPUtil.putString(Defines.OFFSET, it.result?.offset)
                        it.result?.offset?.toInt()?.let { offset ->
                            PrintPageConstants.setPrintHorizontalOffset(offset)
                        }
                        SPUtil.putString(Defines.PHONE_QR_CODE, it.result?.phoneQrCode)
                        SPUtil.putString(Defines.PUBLIC_QR_CODE, it.result?.publicQrCode)
                        ApiConfig.getInstance().builder.machine(it.result?.machineCode)
                        liveDataInitMachineLiveData.postValue(it.result)
                    } else {
                        LaunchHelper.getInstance().launch(BaseApplication.getAppContext(), HomeActivity::class.java)
                        exitProcess(1)
                    }
                }, {
                    errorException.postValue(it)
                }))
    }

    /**
     * 相框
     */
    fun initRahmen() {
        compositeDisposable.add(api.rahmenInit()
                .subscribeOn(Schedulers.io())//在异步线程中执行
                .observeOn(AndroidSchedulers.mainThread())//切换回主线程
                .subscribe({
                    it.result?.let { data ->
                        photoFrameData.add(FrameBo())
                        for (a in data) {
                            val data = FrameBo()
                            data.url = a.image
                            photoFrameData.add(data)
                        }
                        liveDataRefreshLiveData.postValue(null)
                    }
                }, {}))
    }

    /**
     * 获取轮播图
     */
    fun initScrollView() {
        ThreadManager.netService.execute {
            val banner = RequestUtil.call(api.banner())
            banner?.let {
                liveDataInitScrollerViewpagerLiveData.postValue(it)
            }
        }
    }

    /**
     * 清楚轮询
     */
    fun cancelPollingPrint() {
        compositeDisposablePolling.dispose()

    }

    /**
     * 显示二维码的dialog
     */
    fun showQRCodeDialog(fragmentManager: FragmentManager, qrCode: String) {
        val fragment = QRCodeFragment()
        fragment.content = (qrCode)
        val builder = FragmentDialogWrapper.Builder(fragmentManager, fragment, true)
        builder.setPosition(Gravity.CENTER)
        fragment.dialogFragment = builder.builder()
    }

    fun onDestroy() {
        compositeDisposablePolling.dispose()
        compositeDisposable.dispose()
        cmdRunnable.stop = true
    }
}